package com.yyfax.pay.common.aspect;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.yyfax.framework.common.Log;
import com.yyfax.framework.filter.CacheHttpServletRequestWrapper;
import com.yyfax.framework.yyfax.YYFaxSignUtil;
import com.yyfax.framework.yyfax.enums.YesNoEnum;
import com.yyfax.pay.common.constants.PayConstants;
import com.yyfax.pay.common.exception.PayExceptionCode;
import com.yyfax.pay.config.data.service.MerchantConfigService;
import com.yyfax.pay.config.model.po.MerchantConfigPO;

/**
 * 验签切面
 * 
 * @author buyi
 * @date 2017-09-14 14:29:53
 * @since v2.0.0
 */
@Aspect
public class CheckHeaderSignAspect {
	private Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private MerchantConfigService merchantConfigService;

	@Before("execution(public * com.yyfax..*.controller..*.*(..)) and @annotation(com.yyfax.pay.common.annotation.HeaderSign)")
	public void doCheckHeaderSign(JoinPoint point) throws Exception {
		final String op = "CheckHeaderSignAspect.doCheckHeaderSign";
		logger.debug(Log.op(op).msg("进入http请求头验签逻辑").toString());

		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes sra = (ServletRequestAttributes) ra;
		HttpServletRequest request = sra.getRequest();
		if (!(request instanceof CacheHttpServletRequestWrapper)) {
			logger.error(Log.op(op).msg("HTTP请求报文头验签，request类型非指定的CacheHttpServletRequestWrapper").kv("requestType", request.getClass()).toString());
			throw PayExceptionCode.SYS_ERROR.exp();
		}

		CacheHttpServletRequestWrapper cacheRequest = (CacheHttpServletRequestWrapper) sra.getRequest();

		// 请求接口
		String sign = cacheRequest.getHeader(PayConstants.FIELD_SIGN);
		String merchantCode = cacheRequest.getHeader(PayConstants.FIELD_MERCHANT_CODE);
		
		if (StringUtils.isBlank(sign) || StringUtils.isBlank(merchantCode)) {
			logger.warn(Log.op(op).msg("请求头部关键字缺失，无法验签").kv("sign", sign).kv("merchantCode", merchantCode).toString());
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}

		MerchantConfigPO merchantConfigPO = merchantConfigService.queryByMerchantCode(merchantCode);
		if (merchantConfigPO == null || !YesNoEnum.YES.isValue(merchantConfigPO.getState())) {
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}

		String signKey = merchantConfigPO.getSignKey();

		String bodyStr = cacheRequest.getBodyContent();
		if (StringUtils.isBlank(bodyStr)) {
			throw PayExceptionCode.ERROR_ILL_PARAMETER.expMsg("请求参数不能为空");
		}

		boolean isSign = YYFaxSignUtil.checkHeaderSign(signKey, bodyStr, sign);

		if (!isSign) {
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}
	}
}
